﻿#region Copyright and License Notice
// Copyright (C)2010-2012 - Rob Levine and other contributors
// http://configgen.codeplex.com
// 
// This file is part of ConfigGen.
// 
// ConfigGen is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// ConfigGen is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License and 
// the GNU Lesser General Public License along with ConfigGen.  
// If not, see <http://www.gnu.org/licenses/>.
#endregion
using System.Collections.Generic;
using ConfigGen.Core.ConfigurationSettings;
using ConfigGen.Core.SettingsLoader;
using NUnit.Framework;
// ReSharper disable InconsistentNaming

namespace ConfigGen.Core.Tests.EndToEndTests
{
    [TestFixture]
    public class DefaultSettingsCombinerTests
    {
        
        [Test]
        public void default_settings_appended_to_local_settings()
        {
            //Arrange
            var sut = new DefaultSettingsCombiner();
          
            var machineA = GenerateLocalSettings("A");
            var machineB = GenerateLocalSettings("B");
            var machineC = GenerateLocalSettings("C");
            var machineD = GenerateLocalSettings("D");
            var machineE = GenerateLocalSettings("E");
           
            var localSettings = new MachinesConfigurationCollection(new List<MachineConfigurationSettings> { machineA, machineB, machineC, machineD, machineE  });

            var defaultA = GenerateDefaultSettings("A");
            var defaultB = GenerateDefaultSettings("B");
            var defaultC = GenerateDefaultSettings("C");
            var defaultD = GenerateDefaultSettings("D");
            var defaultE = GenerateDefaultSettings("E");

            var defaultSettings = new MachinesConfigurationCollection(new List<MachineConfigurationSettings> { defaultA, defaultB, defaultC, defaultD, defaultE });
            
            //Act
            var result = sut.Combine(localSettings, defaultSettings);

            //Assert
            Assert.AreEqual("A1", result.GetMachineConfigurationSettings("A").GetConfigurationSetting("1").Value);
            Assert.AreEqual("B1", result.GetMachineConfigurationSettings("B").GetConfigurationSetting("1").Value);
            Assert.AreEqual("C1", result.GetMachineConfigurationSettings("C").GetConfigurationSetting("1").Value);
            Assert.AreEqual("D1", result.GetMachineConfigurationSettings("D").GetConfigurationSetting("1").Value);
            Assert.AreEqual("E1", result.GetMachineConfigurationSettings("E").GetConfigurationSetting("1").Value);

            Assert.AreEqual("A5", result.GetMachineConfigurationSettings("A").GetConfigurationSetting("5").Value);
            Assert.AreEqual("B5", result.GetMachineConfigurationSettings("B").GetConfigurationSetting("5").Value);
            Assert.AreEqual("C5", result.GetMachineConfigurationSettings("C").GetConfigurationSetting("5").Value);
            Assert.AreEqual("D5", result.GetMachineConfigurationSettings("D").GetConfigurationSetting("5").Value);
       
            Assert.AreEqual("A6", result.GetMachineConfigurationSettings("A").GetConfigurationSetting("6").Value);
            Assert.AreEqual("B6", result.GetMachineConfigurationSettings("B").GetConfigurationSetting("6").Value);
            Assert.AreEqual("C6", result.GetMachineConfigurationSettings("C").GetConfigurationSetting("6").Value);
            Assert.AreEqual("D6", result.GetMachineConfigurationSettings("D").GetConfigurationSetting("6").Value);
     
        }

        [Test]
        public void machine_unique_to_default_settings_ignored()
        {
            //Arrange
            var sut = new DefaultSettingsCombiner();

            var machineA = GenerateLocalSettings("A");
            var machineB = GenerateLocalSettings("B");
          
            var localSettings = new MachinesConfigurationCollection(new List<MachineConfigurationSettings> { machineA, machineB });

            var defaultA = GenerateDefaultSettings("A");
            var defaultB = GenerateDefaultSettings("B");
            var defaultC = GenerateDefaultSettings("C");
          
            var defaultSettings = new MachinesConfigurationCollection(new List<MachineConfigurationSettings> { defaultA, defaultB, defaultC  });

            //Act
            var result = sut.Combine(localSettings, defaultSettings);

            //Assert
            Assert.AreEqual("A1", result.GetMachineConfigurationSettings("A").GetConfigurationSetting("1").Value);
            Assert.AreEqual("B1", result.GetMachineConfigurationSettings("B").GetConfigurationSetting("1").Value);
          
            Assert.AreEqual("A5", result.GetMachineConfigurationSettings("A").GetConfigurationSetting("5").Value);
            Assert.AreEqual("B5", result.GetMachineConfigurationSettings("B").GetConfigurationSetting("5").Value);
           
            Assert.AreEqual("A6", result.GetMachineConfigurationSettings("A").GetConfigurationSetting("6").Value);
            Assert.AreEqual("B6", result.GetMachineConfigurationSettings("B").GetConfigurationSetting("6").Value);

            Assert.IsNull(result.GetMachineConfigurationSettings("C"));

        }

        [Test]
        public void local_setting_overrides_default_setting()
        {
            //Arrange
            var sut = new DefaultSettingsCombiner();

            var machineA = GenerateLocalSettings("A");
            var machineB = GenerateLocalSettings("B");
            var machineC = GenerateLocalSettings("C");
            var machineD = GenerateLocalSettings("D");
            var machineE = GenerateLocalSettings("E");

            var localSettings = new MachinesConfigurationCollection(new List<MachineConfigurationSettings> { machineA, machineB, machineC, machineD, machineE });

            var defaultA = GenerateDefaultSettingsWithMAachine4("A");
            var defaultB = GenerateDefaultSettingsWithMAachine4("B");
            var defaultC = GenerateDefaultSettingsWithMAachine4("C");
            var defaultD = GenerateDefaultSettingsWithMAachine4("D");
            var defaultE = GenerateDefaultSettingsWithMAachine4("E");

            var defaultSettings = new MachinesConfigurationCollection(new List<MachineConfigurationSettings> { defaultA, defaultB, defaultC, defaultD, defaultE });

            //Act
            var result = sut.Combine(localSettings, defaultSettings);

            //Assert
            Assert.AreEqual("A4", result.GetMachineConfigurationSettings("A").GetConfigurationSetting("4").Value);
            Assert.AreEqual("B4", result.GetMachineConfigurationSettings("B").GetConfigurationSetting("4").Value);
            Assert.AreEqual("C4", result.GetMachineConfigurationSettings("C").GetConfigurationSetting("4").Value);
            Assert.AreEqual("D4", result.GetMachineConfigurationSettings("D").GetConfigurationSetting("4").Value);
            Assert.AreEqual("E4", result.GetMachineConfigurationSettings("E").GetConfigurationSetting("4").Value);
        }

        [Test]
        public void default_settings_replaces_missing_local_setting()
        {
            //Arrange
            var sut = new DefaultSettingsCombiner();

            var machineA = GenerateLocalSettingsWithBlanks("A");
            var machineB = GenerateLocalSettingsWithBlanks("B");
            var machineC = GenerateLocalSettingsWithBlanks("C");
            var machineD = GenerateLocalSettingsWithBlanks("D");
            var machineE = GenerateLocalSettingsWithBlanks("E");

            var localSettings = new MachinesConfigurationCollection(new List<MachineConfigurationSettings> { machineA, machineB, machineC, machineD, machineE });

            var defaultA = GenerateDefaultSettingsWithMAachine4("A");
            var defaultB = GenerateDefaultSettingsWithMAachine4("B");
            var defaultC = GenerateDefaultSettingsWithMAachine4("C");
            var defaultD = GenerateDefaultSettingsWithMAachine4("D");
            var defaultE = GenerateDefaultSettingsWithMAachine4("E");

            var defaultSettings = new MachinesConfigurationCollection(new List<MachineConfigurationSettings> { defaultA, defaultB, defaultC, defaultD, defaultE });

            //Act
            var result = sut.Combine(localSettings, defaultSettings);

            //Assert
            Assert.AreEqual("A400", result.GetMachineConfigurationSettings("A").GetConfigurationSetting("4").Value);
            Assert.AreEqual("B400", result.GetMachineConfigurationSettings("B").GetConfigurationSetting("4").Value);
            Assert.AreEqual("C400", result.GetMachineConfigurationSettings("C").GetConfigurationSetting("4").Value);
            Assert.AreEqual("D400", result.GetMachineConfigurationSettings("D").GetConfigurationSetting("4").Value);
            Assert.AreEqual("E400", result.GetMachineConfigurationSettings("E").GetConfigurationSetting("4").Value);
        }
        
        private static MachineConfigurationSettings GenerateLocalSettings(string machine)
        {
            var settings = new List<ConfigurationSetting>
                {
                    new ConfigurationSetting("1", machine + "1"),
                    new ConfigurationSetting("2", machine + "2"),
                    new ConfigurationSetting("3", machine + "3"),
                    new ConfigurationSetting("4", machine + "4"),
                };
            return new MachineConfigurationSettings(machine, "app.Config", settings);
        }

        private static MachineConfigurationSettings GenerateDefaultSettings(string machine)
        {
            var settings = new List<ConfigurationSetting>
                {
                    new ConfigurationSetting("5", machine + "5"),
                    new ConfigurationSetting("6", machine + "6"),
                };
            return new MachineConfigurationSettings(machine, "app.Config", settings);
        }

        private static MachineConfigurationSettings GenerateDefaultSettingsWithMAachine4(string machine)
        {
            var settings = new List<ConfigurationSetting>
                {
                    new ConfigurationSetting("4", machine + "400"), 
                    new ConfigurationSetting("5", machine + "5"),
                    new ConfigurationSetting("6", machine + "6"),
                };
            return new MachineConfigurationSettings(machine, "app.Config", settings);
        }

        private static MachineConfigurationSettings GenerateLocalSettingsWithBlanks(string machine)
        {
            var settings = new List<ConfigurationSetting>
                {
                    new ConfigurationSetting("1", machine + "1"),
                    new ConfigurationSetting("2", machine + "2"), 
                    new ConfigurationSetting("3", machine + "3"),
                    new ConfigurationSetting("4", ""),//Should get overwritten by default setting 400
                };
            return new MachineConfigurationSettings(machine, "app.Config", settings);
        }

    }
}
// ReSharper restore InconsistentNaming